project(Pro)

###设置最小可用cmake版本
cmake_minimum_required(VERSION 3.0)

###检测cpu和os版本
message(STATUS "Generator: ${CMAKE_GENERATOR}")
message(STATUS "Building OS: ${CMAKE_SYSTEM_NAME}")
message(STATUS "Building Processor: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "Compiler: ${CMAKE_C_COMPILER_ID}")

###设置编译模式(默认为deubg模式)
#取消下一行的注释以进入发行版
#
#set(CMAKE_BUILD_TYPE Release) 
#
if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug) 
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
if (CMAKE_BUILD_TYPE MATCHES "debug")
    set(CMAKE_BUILD_TYPE Debug)
else()
    set(CMAKE_BUILD_TYPE Release)
endif()
message(STATUS "Building mode: ${CMAKE_BUILD_TYPE}")

# 使用C/C++11
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED OFF)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
message(STATUS "C/C++ standard: ${CMAKE_CXX_STANDARD}")

message(STATUS "Compiler ID :${CMAKE_C_COMPILER_ID}")

# 设置MSVC编译选项
if (CMAKE_C_COMPILER_ID MATCHES "MSVC")
    message(STATUS "Visual Studio C++ compiler version: ${CMAKE_C_COMPILER_VERSION}")
    if(CMAKE_C_COMPILER_VERSION VERSION_LESS "19")
        message(FATAL_ERROR "The least version of msvc is 19")
    endif()

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /EHsc /Oy- /utf-8 /FI ${PROJECT_SOURCE_DIR}/include/config.h")
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /D DEBUG /Zi /Od")
    set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX /EHsc /Oy- /utf-8 /FI ${PROJECT_SOURCE_DIR}/include/config.h")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D DEBUG /Zi /Od")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")

    set(CMAKE_LINKER_FLAGS "/NXCOMPAT /INCREMENTAL:NO /DYNAMICBASE")
    set(CMAKE_LINKER_FLAGS_DEBUG "/DEBUG /NXCOMPAT /INCREMENTAL:NO /OPT:REF /OPT:ICF /VERBOSE:ICF /VERBOSE:REF")
    set(CMAKE_LINKER_FLAGS_RELEASE "/NXCOMPAT /INCREMENTAL:NO /DYNAMICBASE")
    set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_LINKER_FLAGS})
    set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_LINKER_FLAGS})
    set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_LINKER_FLAGS})
    set(CMAKE_EXE_LINKER_FLAGS_DEBUG ${CMAKE_LINKER_FLAGS_DEBUG})
    set(CMAKE_MODULE_LINKER_FLAGS_DEBUG ${CMAKE_LINKER_FLAGS_DEBUG})
    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG ${CMAKE_LINKER_FLAGS_DEBUG})
    set(CMAKE_EXE_LINKER_FLAGS_RELEASE ${CMAKE_LINKER_FLAGS_RELEASE})
    set(CMAKE_MODULE_LINKER_FLAGS_RELEASE ${CMAKE_LINKER_FLAGS_RELEASE})
    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE ${CMAKE_LINKER_FLAGS_RELEASE})

    # Windows下的build.bat命令
    if (CMAKE_BUILD_TYPE MATCHES "Release")
        file(WRITE build/make.bat "devenv pro.sln /build Release /project all_build")
    else()
        file(WRITE build/make.bat "devenv pro.sln /build Debug /project all_build")
    endif()
endif()

###如果不在windows下，自动按照如下编译
###设置GNU/CLANG编译选项
# gcc/g++ options
if (CMAKE_C_COMPILER_ID MATCHES "GNU")
    if(CMAKE_C_COMPILER_VERSION VERSION_LESS "6.3")
        message(FATAL_ERROR "The least version of gcc is 6.3")
    endif()

    set(CMAKE_C_FLAGS                     "-Wall -Werror -Wno-attributes -include config.h")
    set(CMAKE_C_FLAGS_DEBUG               "-g -DDEBUG")
    set(CMAKE_C_FLAGS_RELEASE             "-O3")
    set(CMAKE_C_FLAGS_MINSIZEREL          "-Os")
    set(CMAKE_C_RELWITHDEBINFO_RELEASE    "-O2")
    set(CMAKE_CXX_FLAGS                   "-Wall -Werror -Wno-attributes -include config.h -ftemplate-backtrace-limit=0 -fno-exceptions")
    set(CMAKE_CXX_FLAGS_DEBUG             "-g -DDEBUG")
    set(CMAKE_CXX_FLAGS_RELEASE           "-O3 -fno-strict-aliasing")
    set(CMAKE_CXX_FLAGS_MINSIZEREL        "-Os")
    set(CMAKE_CXX_RELWITHDEBINFO_RELEASE  "-O2")

    set(CMAKE_EXE_LINKER_FLAGS_DEBUG      "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_MODULE_LINKER_FLAGS_DEBUG   "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG   "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_EXE_LINKER_FLAGS_RELEASE    "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
endif()
###clang options
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
    if(CMAKE_C_COMPILER_VERSION VERSION_LESS "3.5")
        message(FATAL_ERROR "The least version of clang is 3.5")
    endif()

    set(CMAKE_C_FLAGS                     "-Wall -Werror -include db/config.h -Wno-atomic-alignment ")
    set(CMAKE_C_FLAGS_DEBUG               "-g -DDEBUG")
    set(CMAKE_C_FLAGS_MINSIZEREL          "-Os")
    set(CMAKE_C_FLAGS_RELEASE             "-O3")
    set(CMAKE_C_FLAGS_RELWITHDEBINFO      "-O2")
    set(CMAKE_CXX_FLAGS                   "-Wall -Werror -include db/config.h  -fno-exceptions -Wno-delete-non-virtual-dtor -Wno-atomic-alignment -ftemplate-backtrace-limit=0")
    set(CMAKE_CXX_FLAGS_DEBUG             "-g -DDEBUG")
    set(CMAKE_CXX_FLAGS_MINSIZEREL        "-Os")
    set(CMAKE_CXX_FLAGS_RELEASE           "-O3")
    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO    "-O2")

    set(CMAKE_EXE_LINKER_FLAGS_DEBUG      "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_MODULE_LINKER_FLAGS_DEBUG   "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG   "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_EXE_LINKER_FLAGS_RELEASE    "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -s -Bsymbolic -Bsymbolic-functions -Wl,--no-undefined")
endif()

###生成config.h
configure_file(
    ${CMAKE_SOURCE_DIR}/config.h.in
    ${CMAKE_SOURCE_DIR}/include/config.h
    NEWLINE_STYLE UNIX
)

###指定编译子目录
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(release-src)